package service

import (
	"errors"
	"fmt"
	"log"
	"math"

	"github.com/google/uuid"
	"github.com/smash-llj/Nexa-server/global"
	"github.com/smash-llj/Nexa-server/models"
	"github.com/smash-llj/Nexa-server/models/request"
	"github.com/smash-llj/Nexa-server/models/response"
)

var friendService *FriendService

type FriendService struct {
	BaseService
}

func NewFriendService() *FriendService {
	if friendService == nil {
		return &FriendService{
			NewBaseService(),
		}
	}
	return friendService
}

// GetFriendList 获取好友列表
func (f *FriendService) GetFriendList(uId uint) ([]response.GetFriendListResp, error) {
	var friends []response.GetFriendListResp
	err := f.Gorm.
		Table("friend").
		Select("user.username, user.avatar, user.id").
		Joins("JOIN `user` ON user.id = friend.friend_id").
		Where("friend.user_id = ?", uId).
		Scan(&friends).Error

	if err != nil {
		return nil, fmt.Errorf("failed to get friend list: %w", err)
	}
	return friends, nil
}

// GetFriendMessageList 获取聊天记录
func (f *FriendService) GetFriendMessageList(params request.GetFriendMessageReq, userId uint) (*response.MessageResp, error) {
	var totalMessages int64
	var messages []response.MessageListResp
	query := f.Gorm.Model(&models.Message{}).Where("session_id = ? ", params.SessionId)
	if err := query.Count(&totalMessages).Error; err != nil {
		return nil, err
	}
	if err := f.Gorm.Table("message").
		Select("message.*, user.username, user.avatar").
		Joins("LEFT JOIN user ON user.id = message.send_id").
		Where("message.session_id = ?", params.SessionId).
		Scopes(params.PageInfo.Paginate()).
		Order("message.created_at DESC").
		Find(&messages).Error; err != nil {
		return nil, err
	}
	totalPages := int(math.Ceil(float64(totalMessages) / float64(params.PageInfo.PageSize)))
	//更新会话

	err := f.Gorm.Model(&models.Session{}).Where("session_id=? And user_id =?", params.SessionId, userId).Update("unread", 0).Error
	if err != nil {
		log.Print("更新会话记录失败")
		return nil, err
	}
	return &response.MessageResp{
		Messages:   messages,
		Total:      totalMessages,
		TotalPages: totalPages,
	}, nil
}

// SearchFriend 查找好友
func (f *FriendService) SearchFriend(searchParam request.SearchFriendReq) ([]response.SearchFriendResp, error) {
	var result []response.SearchFriendResp
	var users []models.User

	// 查询符合条件的用户
	query := f.Gorm.Model(&models.User{})
	if searchParam.Username != "" {
		query = query.Where("username LIKE ?", "%"+searchParam.Username+"%")
	}
	if searchParam.Id != 0 {
		query = query.Where("uuid = ?", searchParam.Id)
	}
	if err := query.Find(&users).Error; err != nil {
		return nil, err
	}
	userIds := extractUserIds(users)

	friendStatusMap, err := f.getFriendStatusMap(uint(searchParam.UserId), userIds)
	if err != nil {
		return nil, err
	}

	requestMessageMap, err := f.getRequestMessageMap(uint(searchParam.UserId), userIds)
	if err != nil {
		return nil, err
	}

	// 构建响应结果
	for _, user := range users {
		status := global.NoFriend
		if friendStatus, exists := friendStatusMap[int(user.Id)]; exists {
			status = friendStatus
		} else if requestMessageMap[int(user.Id)] {
			status = global.WaitFriend
		}

		result = append(result, response.SearchFriendResp{
			Id:       int(user.Id),
			UUID:     user.UUID,
			Avatar:   user.Avatar,
			Username: user.Username,
			Sign:     user.Sign,
			Status:   status,
		})
	}

	return result, nil
}

// 获取好友状态映射
func (f *FriendService) getFriendStatusMap(userId uint, friendIds []uint) (map[int]int, error) {
	var friends []models.Friend
	if err := f.Gorm.Model(&models.Friend{}).
		Where("user_id = ? AND friend_id IN (?)", userId, friendIds).
		Find(&friends).Error; err != nil {
		return nil, err
	}

	friendStatusMap := make(map[int]int)
	for _, friend := range friends {
		friendStatusMap[int(friend.FriendId)] = friend.Status
	}
	return friendStatusMap, nil
}

// 获取好友请求映射
func (f *FriendService) getRequestMessageMap(userId uint, receiverIds []uint) (map[int]bool, error) {
	var requestMessages []models.RequestMessage
	if err := f.Gorm.Model(&models.RequestMessage{}).
		Where("request_id = ? AND receiver_id IN (?)", userId, receiverIds).
		Find(&requestMessages).Error; err != nil {
		return nil, err
	}

	requestMessageMap := make(map[int]bool)
	for _, msg := range requestMessages {
		requestMessageMap[int(msg.ReceiverId)] = true
	}
	return requestMessageMap, nil
}

// 提取用户Id列表
func extractUserIds(users []models.User) []uint {
	userIds := make([]uint, 0, len(users))
	for _, user := range users {
		userIds = append(userIds, user.Id)
	}
	return userIds
}

// AddFriend 添加好友
func (f *FriendService) AddFriend(userDto request.AddFriendReq, userId int) error {
	var exists bool
	err := f.Gorm.Model(&models.RequestMessage{}).
		Select("1").
		Where("request_id = ? AND receiver_id = ? AND status = ?", userId, userDto.FriendId, global.WaitFriend).
		Limit(1).
		Find(&exists).Error
	if err != nil {
		return fmt.Errorf("查询好友请求失败: %v", err)
	}
	if exists {
		return fmt.Errorf("已经是好友了")
	}
	newFriendRequest := models.RequestMessage{
		RequestId:   userId,
		ReceiverId:  userDto.FriendId,
		Status:      global.WaitFriend,
		Description: userDto.Msg,
	}
	if err := f.Gorm.Create(&newFriendRequest).Error; err != nil {
		return fmt.Errorf("添加好友失败: %v", err)
	}
	return nil
}

// AgreeFriend 同意好友请求
func (f *FriendService) AgreeFriend(dto request.UserFriendReq) (*response.AgreeFriendResp, error) {
	tx := f.Gorm.Begin()
	defer func() {
		if r := recover(); r != nil || tx.Error != nil {
			tx.Rollback()
		}
	}()

	// 1. 查找好友请求
	var msg models.RequestMessage
	if err := tx.Where("request_id = ? AND receiver_id = ? AND status = ?", dto.FriendId, dto.UserId, global.WaitFriend).
		First(&msg).Error; err != nil {
		return nil, fmt.Errorf("查找好友请求失败: %w", err)
	}

	// 2. 更新请求状态
	if err := tx.Model(&msg).Update("status", global.IsFriend).Error; err != nil {
		return nil, fmt.Errorf("更新请求状态失败: %w", err)
	}
	SessionId := uuid.New().String()
	// 3. 创建双向好友关系
	friends := []models.Friend{
		{UserId: dto.UserId, FriendId: dto.FriendId, Status: global.IsFriend, SessionId: SessionId},
		{UserId: dto.FriendId, FriendId: dto.UserId, Status: global.IsFriend, SessionId: SessionId},
	}
	if err := tx.Create(&friends).Error; err != nil {
		return nil, fmt.Errorf("创建好友关系失败: %w", err)
	}

	// 4. 查询好友信息
	var friend models.User
	if err := tx.First(&friend, dto.FriendId).Error; err != nil {
		return nil, fmt.Errorf("查询好友信息失败: %w", err)
	}

	// 5. 提交事务
	if err := tx.Commit().Error; err != nil {
		return nil, fmt.Errorf("提交事务失败: %w", err)
	}

	return &response.AgreeFriendResp{
		Friend:    friend,
		SessionId: SessionId,
	}, nil
}

// RequestFriendList 获取好友请求列表
func (f *FriendService) RequestFriendList(UserId int) ([]models.RequestMessage, error) {
	var FriendList []models.RequestMessage
	err := f.Gorm.Model(&models.RequestMessage{}).Where("receiver_id = ?", UserId).Preload("Receiver").Preload("Request").Find(&FriendList).Error
	if err != nil {
		return []models.RequestMessage{}, err
	}
	return FriendList, nil
}

// DelFriend 删除好友
func (f *FriendService) DelFriend(userDto request.UserFriendReq) error {
	// 先查询是否存在好友关系
	result := f.Gorm.Model(&models.Friend{}).
		Where("user_id = ? AND friend_id = ?", userDto.UserId, userDto.FriendId).
		Limit(1).Find(nil)

	if result.RowsAffected == 0 {
		return errors.New("好友关系不存在")
	}

	if err := f.Gorm.Model(&models.Friend{}).
		Where("user_id = ? AND friend_id = ?", userDto.UserId, userDto.FriendId).
		Update("status", global.FriendStatusDel).Error; err != nil {
		return err
	}
	return nil
}

// DetailFriend 获取好友详情
func (f *FriendService) DetailFriend(friendId, userId uint) (*response.GetFriendDetailResp, error) {
	var friend models.Friend
	err := f.Gorm.Model(&models.Friend{}).Preload("Friend").Where("friend_id = ? AND user_id = ?", friendId, userId).First(&friend).Error
	if err != nil {
		return nil, err
	}
	return &response.GetFriendDetailResp{
		User:      friend.Friend,
		SessionId: friend.SessionId,
	}, nil
}
